{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1 pad()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "tf.pad函数主要是用来对tensor的大小进行扩展，包括水平、垂直、深度(通道)等,方法定义如下：\n",
    "\n",
    "pad(tensor, paddings, mode=\"CONSTANT\", name=None, constant_values=0)\n",
    "\n",
    "输入参数：\n",
    "\n",
    "- tensor:输入的tensor\n",
    "\n",
    "- paddings:设置填充的大小\n",
    "\n",
    "- mode:填充方式，默认是CONSTANT,还有REFLECT和SYMMETRIC\n",
    "\n",
    "- name:名称\n",
    "\n",
    "- constant_values：CONSTANT填充方式的填充值,默认是0\n",
    "\n",
    "参数paddings必须是形状为（n, 2）的一个list，这里的n是tensor的秩，也就是维度大小。例如当tensor为一个shape为（12，）的tensor时，paddings必须是形如[[x，y]]的一个list，x表示在第一维度前填充值的个数，y表示在第一维度后填充值的个数：\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = tf.range(1,13)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=3, shape=(12,), dtype=int32, numpy=array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12], dtype=int32)>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=5, shape=(15,), dtype=int32, numpy=\n",
       "array([ 0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12],\n",
       "      dtype=int32)>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.pad(a, [[3,0]])  # 3表示在第一维度前填充3个0,0表示不填充"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当tensor是二维时，paddings必须是shape为（2,2）的list："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = tf.reshape(a, [3, 4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=7, shape=(3, 4), dtype=int32, numpy=\n",
       "array([[ 1,  2,  3,  4],\n",
       "       [ 5,  6,  7,  8],\n",
       "       [ 9, 10, 11, 12]], dtype=int32)>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=10, shape=(5, 7), dtype=int32, numpy=\n",
       "array([[ 3,  3,  3,  3,  3,  3,  3],\n",
       "       [ 3,  3,  3,  1,  2,  3,  4],\n",
       "       [ 3,  3,  3,  5,  6,  7,  8],\n",
       "       [ 3,  3,  3,  9, 10, 11, 12],\n",
       "       [ 3,  3,  3,  3,  3,  3,  3]], dtype=int32)>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.pad(a, [[1,1],[3,0]], constant_values=3)  # 第一维度前后各填充一行，第二维度前填充两行，后不填充，填充值为3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于3维tensor，paddings是一个shape为（3,2）的list："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = tf.reshape(a, [2, 2, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=12, shape=(2, 2, 3), dtype=int32, numpy=\n",
       "array([[[ 1,  2,  3],\n",
       "        [ 4,  5,  6]],\n",
       "\n",
       "       [[ 7,  8,  9],\n",
       "        [10, 11, 12]]], dtype=int32)>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=14, shape=(3, 4, 4), dtype=int32, numpy=\n",
       "array([[[ 0,  0,  0,  0],\n",
       "        [ 0,  0,  0,  0],\n",
       "        [ 0,  0,  0,  0],\n",
       "        [ 0,  0,  0,  0]],\n",
       "\n",
       "       [[ 0,  0,  0,  0],\n",
       "        [ 0,  1,  2,  3],\n",
       "        [ 0,  4,  5,  6],\n",
       "        [ 0,  0,  0,  0]],\n",
       "\n",
       "       [[ 0,  0,  0,  0],\n",
       "        [ 0,  7,  8,  9],\n",
       "        [ 0, 10, 11, 12],\n",
       "        [ 0,  0,  0,  0]]], dtype=int32)>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.pad(a, [[1, 0],[1,1],[1,0]])  # 第一维度前填充1块数据，后不填充，第二维度前后各填充1行，第三维度前填充1列，后不填充"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = tf.range(1,13)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = tf.reshape(a,[3,4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=20, shape=(3, 4), dtype=int32, numpy=\n",
       "array([[ 1,  2,  3,  4],\n",
       "       [ 5,  6,  7,  8],\n",
       "       [ 9, 10, 11, 12]], dtype=int32)>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当指定填充模式mode为'REFLECT'时，指的是以各维度边缘为对称轴进行填充（不包括边缘数据也就是对称轴本身），且填充的规模不能大于该维度原有规模-1："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=22, shape=(6, 8), dtype=int32, numpy=\n",
       "array([[12, 11, 10,  9, 10, 11, 12, 11],\n",
       "       [ 8,  7,  6,  5,  6,  7,  8,  7],\n",
       "       [ 4,  3,  2,  1,  2,  3,  4,  3],\n",
       "       [ 8,  7,  6,  5,  6,  7,  8,  7],\n",
       "       [12, 11, 10,  9, 10, 11, 12, 11],\n",
       "       [ 8,  7,  6,  5,  6,  7,  8,  7]], dtype=int32)>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.pad(a, [[2,1],[3,1]],mode='REFLECT')  # 对第二个维度填充时，如果大于3就回产生异常，因为3已经可以把第二维度所有数据复制一遍"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "SYMMETRIC填充模式与REFLECT填充模式一样，都是以边缘为对称轴进行赋值填充，不过SYMMETRIC模式会对对称轴进行赋值，所以指定的规模最大可以为原规模："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=24, shape=(6, 9), dtype=int32, numpy=\n",
       "array([[ 8,  7,  6,  5,  5,  6,  7,  8,  8],\n",
       "       [ 4,  3,  2,  1,  1,  2,  3,  4,  4],\n",
       "       [ 4,  3,  2,  1,  1,  2,  3,  4,  4],\n",
       "       [ 8,  7,  6,  5,  5,  6,  7,  8,  8],\n",
       "       [12, 11, 10,  9,  9, 10, 11, 12, 12],\n",
       "       [12, 11, 10,  9,  9, 10, 11, 12, 12]], dtype=int32)>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.pad(a, [[2,1],[4,1]],mode='SYMMETRIC')  # 这时候对第二个维度填充规模可以为4，但是超过4旧货产生异常"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2 tile()\n",
    "\n",
    "tile()方法对指定维度进行复制，定义如下：  \n",
    "\n",
    "tile(input, multiples, name=None)：  \n",
    " - input：需要复制的tensor\n",
    " - multiples: 各维度需要复制的次数，0表示去除数据，1表示不复制，2表示复制一次\n",
    " \n",
    "参数multiples是一个长度与tensor的秩相等的list，例如当tensor的shape为（12，）时，multiples的shape也必须为只有一个元素的list，例如multiples=[2],表示对第一维度复制1次："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = tf.range(12)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=33, shape=(24,), dtype=int32, numpy=\n",
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  0,  1,  2,  3,  4,\n",
       "        5,  6,  7,  8,  9, 10, 11], dtype=int32)>"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.tile(a,[2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当tensor的shape为（3,4）时，multiples是一个包含两个元素的list："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = tf.reshape(a, [3,4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=37, shape=(6, 12), dtype=int32, numpy=\n",
       "array([[ 0,  1,  2,  3,  0,  1,  2,  3,  0,  1,  2,  3],\n",
       "       [ 4,  5,  6,  7,  4,  5,  6,  7,  4,  5,  6,  7],\n",
       "       [ 8,  9, 10, 11,  8,  9, 10, 11,  8,  9, 10, 11],\n",
       "       [ 0,  1,  2,  3,  0,  1,  2,  3,  0,  1,  2,  3],\n",
       "       [ 4,  5,  6,  7,  4,  5,  6,  7,  4,  5,  6,  7],\n",
       "       [ 8,  9, 10, 11,  8,  9, 10, 11,  8,  9, 10, 11]], dtype=int32)>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.tile(a, [2,3])  # 第一维度复制1次，第二维度复制2次"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当tensor的shape为(2,2,3时，multiples是一个包含3个元素list："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = tf.reshape(a, [2,2,3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tf.Tensor: id=41, shape=(4, 2, 6), dtype=int32, numpy=\n",
       "array([[[ 0,  1,  2,  0,  1,  2],\n",
       "        [ 3,  4,  5,  3,  4,  5]],\n",
       "\n",
       "       [[ 6,  7,  8,  6,  7,  8],\n",
       "        [ 9, 10, 11,  9, 10, 11]],\n",
       "\n",
       "       [[ 0,  1,  2,  0,  1,  2],\n",
       "        [ 3,  4,  5,  3,  4,  5]],\n",
       "\n",
       "       [[ 6,  7,  8,  6,  7,  8],\n",
       "        [ 9, 10, 11,  9, 10, 11]]], dtype=int32)>"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.tile(a, [2,1,2])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "study_python",
   "language": "python",
   "name": "study_python"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
